#!/usr/local/bin/python
# coding: utf8
import os
import sys
import json
import shutil
import logging
import datetime
import ConfigParser
import subprocess

ABS_PATH = os.path.abspath(__file__)
BASE_DIR = os.path.dirname(ABS_PATH)
BASE_NAME = os.path.basename(ABS_PATH)
CONF = os.path.join(BASE_DIR, 'vipdomain.conf')

cf = ConfigParser.ConfigParser()
with open(CONF, 'r') as f:
    cf.readfp(f)

cn_vip_list_path = cf.get('input_file', 'cn_vip_list_path')
cdn_vip_list_path = cf.get('input_file', 'cdn_vip_list_path')

tld_vipdomain_dir = cf.get('output_file', 'tld_vipdomain_dir')

server1 = cf.get('other', 'server1')
dig = cf.get('other', 'dig_path')


def sys_cmd(cmd):
    print(cmd)
    sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return sp.communicate()

def print_and_info_message(message):
    logging.info(message)
    print(message)

# bak the  sld/* 
def bak_old_files(now, tld_file_lst):
    os.chdir(tld_vipdomain_dir)
    for f in tld_file_lst:
        if os.path.exists(f):
            shutil.move(f, f+'_'+now)

            message = 'Finished backup {0} to {1}.'.format(os.path.join(tld_vipdomain_dir, f), os.path.join(tld_vipdomain_dir, f+'_'+now))
            print_and_info_message(message)

def get_authority_info(lines, tld_dic, domain_dic, ns_dic):
    for line in lines: 
        zone = line[:-1]
#       print(zone)
        # xn--efvx5o.xn--fiqs8s
        if zone.lower().endswith('xn--fiqs8s.'):
            tld_dic.setdefault('xn--fiqs8s.', []).append(zone.lower())
        # xn--vuq945an13b.xn--55qx5d
        elif zone.lower().endswith('xn--55qx5d.'):
            tld_dic.setdefault('xn--55qx5d.', []).append(zone.lower())
        # xn--vuq945an13b.xn--io0a7i
        elif zone.lower().endswith('xn--io0a7i.'):
            tld_dic.setdefault('xn--io0a7i.', []).append(zone.lower())
        # xn--vuq945an13b.cn
        elif zone.lower().endswith('cn.') and zone.lower().startswith('xn--'):
            tld_dic.setdefault('xn--cn.', []).append(zone.lower())
        # wlaqz.cn
        else:
            tld_dic.setdefault('cn.', []).append(zone)

        cmd = '{0} @{1} any {2}'.format(dig, server1, zone)
        out, err = sys_cmd(cmd)
        for out_line in out.split('\n')[:-1]:
            if ';' in out_line:
                continue
            if len(out_line.split()) < 4:
                continue
            if out_line.split()[3] == 'NS':
                domain, ttl, qtype, qclass, ns = out_line.split()
                domain_dic.setdefault(domain.lower(), set()).add(ns.lower())
                continue
            if out_line.split()[3] in ['A', 'AAAA']:
                ns, ttl, qtype, qclass, glue = out_line.split()
                ns_dic.setdefault(ns.lower(), {}).setdefault(qclass.lower(), set()).add(glue)
                continue

# the full update program will need the sld
def generate_sld_files(now, tld_dic, sld_lst):
    eng_cn_sld_lst = []
    os.chdir(sld_vipdomain_dir)
    cn_domain_lst = tld_dic['cn.']
    for sld in sld_lst:
        sld_domain_lst = filter(lambda x: '.'+sld in x, cn_domain_lst)
        if sld_domain_lst:
            eng_cn_sld_lst.extend(sld_domain_lst)
            with open(sld, 'w') as f:
                json.dump(sld_domain_lst, f, indent=4)

                message = 'Finished generate {0}.'.format(os.path.join(sld_vipdomain_dir, sld))
                print_and_info_message(message)

    return eng_cn_sld_lst


# the full update program will need the eng_cn_exclude_sld
def generate_eng_cn_exclued_sld(now, eng_cn_lst, eng_cn_sld_lst):
    eng_cn_exclude_sld_lst = list(set(eng_cn_lst) - set(eng_cn_sld_lst))
    os.chdir(eng_cn_vipdomain_dir)
    with open('eng_cn', 'w') as f:
        json.dump(eng_cn_exclude_sld_lst, f, indent=4) 

        message = 'Finished generate {0}.'.format(os.path.join(eng_cn_vipdomain_dir, 'eng_cn'))
        print_and_info_message(message)


# the vipdomain check program whill need the domain_dic, ns_dic, tld_dic
def generate_tld_files(now, info_dic):
    os.chdir(tld_vipdomain_dir)
    for tld_file, dic in info_dic.items():
        with open(tld_file, 'w') as f:
            json.dump(dic, f, indent=4)

            message = 'Finished generate {0}.'.format(os.path.join(tld_vipdomain_dir, tld_file))
            print_and_info_message(message)
    

def generate_new_files(now, tld_file_lst):
    tld_dic = {}
    domain_dic = {}
    ns_dic = {}

    with open(cn_vip_list_path, 'r') as f:
        cn_lines = f.readlines()

    with open(cdn_vip_list_path, 'r') as f:
        cdn_lines= f.readlines()

    get_authority_info(cn_lines, tld_dic, domain_dic, ns_dic)
    get_authority_info(cdn_lines, tld_dic, domain_dic, ns_dic)

    for domain, ns_lst in domain_dic.items():
        domain_dic[domain]= list(ns_lst)
    for ns, glue_type_dic in ns_dic.items():
        for glue_type, glue_lst in glue_type_dic.items():
            glue_type_dic[glue_type] = list(glue_lst)

    generate_tld_files(now, {'vip_tld_dic': tld_dic, 'vip_ns_dic': ns_dic, 'vip_domain_dic': domain_dic})


def main():
    tld_file_lst = ['vip_domain_dic', 'vip_ns_dic', 'vip_tld_dic']

    now = datetime.datetime.now().strftime('%Y%m%d%H%M')
    logging.basicConfig(filename=os.path.join(BASE_DIR, 'log', 'log.log'), level=logging.INFO , format='%(asctime)s: %(levelname)s: %(message)s')

    bak_old_files(now, tld_file_lst)
    generate_new_files(now, tld_file_lst)


if __name__ == '__main__':
    main()
